﻿Imports System.Diagnostics.Contracts
Imports AutoMapper
Imports DomusDotNet.Sbm.Wcf.Interfaces
Imports DomusDotNet.Sbm.Services.Interfaces
Imports Microsoft.Practices.Unity
Imports DomusDotNet.Sbm.Services

Namespace Wcf.Implementations
    Public MustInherit Class SharedBookshelfService
        Implements ISharedBookshelfService
        Public Sub New()
            Me.SetContainer()
        End Sub

        Protected MustOverride Sub SetContainer()

        Private _Container As IUnityContainer

        Protected Property Container As IUnityContainer
            Get
                Return Me._Container
            End Get
            Set(ByVal value As IUnityContainer)

                ''sorry Massimo, it requires rewriter ON
                ''Contract.Requires(Of ArgumentNullException)(value IsNot Nothing, "Container non può essere null.")
                If (value Is Nothing) Then
                    Throw New ArgumentNullException("container")
                End If

                Me._Container = value
            End Set
        End Property

        Public Function BookReservation(request As Requests.BookReservationRequest) As Responses.BookReservationResponse Implements Interfaces.ISharedBookshelfService.BookReservation
            Dim response = New Responses.BookReservationResponse() With {.Result = True}
            response.SessionGUID = request.SessionGUID
            response.BookId = request.BookId
            System.Threading.Thread.Sleep(2000)
            Try
                Using authSrv = Container.Resolve(Of IAuthenticationService)()
                    If authSrv.ValidateSessionGuid(request.SessionGUID) Then
                        Using srv = Container.Resolve(Of IBookService)()
                            If Not srv.Reserve(request.BookId, request.ReservationName) Then
                                response.ReservationResult = False
                                response.Errors.AddRange(From e In authSrv.Errors
                                                         Select Mapper.Map(Of ServiceError, [Error])(e))
                            Else
                                response.ReservationResult = True
                            End If
                        End Using
                    Else
                        response.Result = False
                    End If
                End Using
            Catch ex As Exception
                response.Result = False
                response.Errors.Add(New [Error] With {.Code = "SearchBooks",
                                                    .Message = "Errore nella prenotazione del libro"})
            End Try
            Return response
        End Function

        Public Function Login(request As Requests.LoginRequest) As Responses.LoginResponse Implements Interfaces.ISharedBookshelfService.Login
            Dim response = New Responses.LoginResponse() With {.Result = True}
            System.Threading.Thread.Sleep(2000)
            Try
                Using srv = Container.Resolve(Of IAuthenticationService)()
                    response.Result = srv.ValidateUser(request.UserName, request.Password)
                    If response.Result Then
                        response.SessionGUID = Guid.NewGuid().ToString()
                    Else
                        response.SessionGUID = Nothing
                        response.Errors.AddRange(From e In srv.Errors
                                                 Select Mapper.Map(Of ServiceError, [Error])(e))
                    End If
                End Using
            Catch ex As Exception
                response.Result = False
                response.Errors.Add(New [Error] With {.Code = "Login",
                                                    .Message = "Errore nella procedura di Login"})
            End Try
            Return response
        End Function

        Public Function Logout(request As Requests.LogoutRequest) As Responses.LogoutResponse Implements Interfaces.ISharedBookshelfService.Logout
            Dim response = New Responses.LogoutResponse() With {.Result = True}
            System.Threading.Thread.Sleep(2000)
            Try
                Using srv = Container.Resolve(Of IAuthenticationService)()
                    response.Result = srv.ValidateSessionGuid(request.SessionGUID)
                    If Not response.Result Then
                        response.Errors.AddRange(From e In srv.Errors
                                                 Select Mapper.Map(Of ServiceError, [Error])(e))
                    End If
                End Using
            Catch ex As Exception
                response.Result = False
                response.Errors.Add(New [Error] With {.Code = "Login",
                                                    .Message = "Errore nella procedura di Login"})
            End Try
            Return response
        End Function
        
        Public Function SearchBooks(request As Requests.SearchBooksRequest) As Responses.SearchBooksResponse Implements Interfaces.ISharedBookshelfService.SearchBooks
            Dim response = New Responses.SearchBooksResponse() With {.Result = True}
            response.SessionGUID = request.SessionGUID
            System.Threading.Thread.Sleep(2000)
            Try
                Using authSrv = Container.Resolve(Of IAuthenticationService)()
                    If authSrv.ValidateSessionGuid(request.SessionGUID) Then
                        Using srv = Container.Resolve(Of IBookService)()
                            Dim availableFilter As Boolean? = Nothing
                            If request.BookStatusesFilter IsNot Nothing Then
                                If request.BookStatusesFilter.Contains(BookStatusEnum.Available) Then
                                    If Not request.BookStatusesFilter.Contains(BookStatusEnum.Booked) And Not request.BookStatusesFilter.Contains(BookStatusEnum.Booked) Then
                                        availableFilter = True
                                    End If
                                Else
                                    If request.BookStatusesFilter.Contains(BookStatusEnum.Booked) Or request.BookStatusesFilter.Contains(BookStatusEnum.Booked) Then
                                        availableFilter = False
                                    End If
                                End If
                            End If
                            response.Books = (From b In srv.Search(request.AuthorFilter,
                                                                  request.TitleFilter,
                                                                  request.PublishDateFromFilter,
                                                                  request.PublishDateToFilter,
                                                                  availableFilter)
                                              Select Mapper.Map(Of ObjectModel.Book, Wcf.BookBase)(b)).ToList()
                        End Using
                    Else
                        response.Result = False
                        response.Errors.AddRange(From e In authSrv.Errors
                                                 Select Mapper.Map(Of ServiceError, [Error])(e))
                    End If
                End Using
            Catch ex As Exception
                response.Result = False
                response.Errors.Add(New [Error] With {.Code = "SearchBooks",
                                                    .Message = "Errore nella ricerca dei libri"})
            End Try
            Return response
        End Function
    End Class
End Namespace